#ifndef _LAPLACESCHEME_H_
#define _LAPLACESCHEME_H_

#include "Equations/ScalarEquation.hpp"

namespace Tuna {

  template <typename T, int Dim> class LaplaceScheme;

  template <typename T>
  struct Typeinfo <LaplaceScheme<T, 1> > {
    typedef T prec_t;
    enum { Dim = 1 };
  };

  template <typename T>
  struct Typeinfo <LaplaceScheme<T, 2> > {
    typedef T prec_t;
    enum { Dim = 2 };
  };

  template <typename T>
  struct Typeinfo <LaplaceScheme<T, 3> > {
    typedef T prec_t;
    enum { Dim = 3 };
  };
  
  template<typename Tprec, int Dim>
  class LaplaceScheme : public ScalarEquation<LaplaceScheme<Tprec, Dim> >
  {
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::aE;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::aW;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::aN;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::aS;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::aF;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::aB;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::aP;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::sp;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::dx;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::dy;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::dz;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::bi;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::ei;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::bj;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::ej;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::bk;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::ek;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::applyBoundaryConditions1D;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::applyBoundaryConditions2D;
    using GeneralEquation<ScalarEquation<LaplaceScheme<Tprec, Dim> > >::applyBoundaryConditions3D;
    using ScalarEquation<LaplaceScheme<Tprec, Dim> >::Gamma;

  public:
    typedef Tprec prec_t;
    typedef typename TunaArray<prec_t, Dim >::huge ScalarField;
    
    LaplaceScheme() : ScalarEquation<LaplaceScheme<prec_t, Dim > >() { }    
    ~LaplaceScheme() { };
 
 /*!
   * FVM coefficients calculations in 1D.
   */
  inline bool calcCoefficients1D(); 

  /*!
   * FVM coefficients calculations in 2D.
   */
  inline bool calcCoefficients2D();

  /*!
   * FVM coefficients calculations in 3D.
   */
  inline bool calcCoefficients3D();
   
    inline void printInfo() { std::cout << " LaplaceScheme "; }
  };

} // Tuna namespace

#include "../../src/Schemes/LaplaceScheme.cpp"

#endif //_LAPLACESCHEME_H_

















